package main

import (
	"fmt"
	"gaojunyublockchain/block"
	"gaojunyublockchain/wallet"
	"log"

	"github.com/fatih/color"
)

func init() {

	color.Red("██████╗ ██╗      ██████╗  ██████╗██╗  ██╗ ██████╗██╗  ██╗ █████╗ ██╗███╗   ██╗")
	color.Red("██╔══██╗██║     ██╔═══██╗██╔════╝██║ ██╔╝██╔════╝██║  ██║██╔══██╗██║████╗  ██║")
	color.Red("██████╔╝██║     ██║   ██║██║     █████╔╝ ██║     ███████║███████║██║██╔██╗ ██║")
	color.Red("██╔══██╗██║     ██║   ██║██║     ██╔═██╗ ██║     ██╔══██║██╔══██║██║██║╚██╗██║")
	color.Red("██████╔╝███████╗╚██████╔╝╚██████╗██║  ██╗╚██████╗██║  ██║██║  ██║██║██║ ╚████║")
	color.Red("╚═════╝ ╚══════╝ ╚═════╝  ╚═════╝╚═╝  ╚═╝ ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝╚═╝  ╚═══╝")

	log.SetPrefix("Blockchain: ")
}

func main() {

	wallet_gaojunyu := wallet.LoadWallet(block.MINING_ACCOUNT_ADDRESS) //矿工
	fmt.Printf("blockAddress_gaojunyu:%s\n", wallet_gaojunyu.BlockchainAddress())

	swk := wallet.FromPriKeyStrToPubKey("36a922ccead761032667b73a0427db318b37d41dc3b8d2a73555ef0186cafbe78")
	fmt.Println("PrivateKeyStr:", swk.PrivateKeyStr())
	fmt.Println("PublicKeyStr", swk.PublicKeyStr())
	fmt.Println("BlockchainAddress==>", swk.BlockchainAddress())

	zbj := wallet.FromPriKeyStrToPubKey("36a922ccead761032667b73a0427d8888b37d41dc3b8d2a73555ef0186cafbe78")
	fmt.Println("PrivateKeyStr:", zbj.PrivateKeyStr())
	fmt.Println("PublicKeyStr", zbj.PublicKeyStr())
	fmt.Println("BlockchainAddress==>", zbj.BlockchainAddress())

	gjy := wallet.FromPriKeyStrToPubKey("36a922adsdead761032667b73a0427d8888b37d41dc3b8d2a73555ef0186cafbe78")
	fmt.Println("PrivateKeyStr:", gjy.PrivateKeyStr())
	fmt.Println("PublicKeyStr", gjy.PublicKeyStr())
	fmt.Println("BlockchainAddress==>", gjy.BlockchainAddress())

	fmt.Println("PrivateKey==>\n", swk.PrivateKey())
	fmt.Println("PublicKey==>\n", swk.PublicKey())

	wallet.FromPriKeyStrToPubKey("39995dad22adsdead761032667b73a0427d8328b37d41dc3b8d2a73555ef0186cafbe78")

	color.Yellow("孙悟空的account:%s\n", swk.BlockchainAddress())
	color.Yellow("猪八戒的account:%s\n", zbj.BlockchainAddress())
	color.Yellow("矿  工的account:%s\n", gjy.BlockchainAddress())

	blockchain := block.NewBlockchain(wallet_gaojunyu.BlockchainAddress(), 5000)
	blockchain.Mining()
	blockchain.Print()
	//钱包 提交一笔交易
	t := wallet.NewTransaction( //NewTransaction的参数是不是可以优化一下？
		gjy.PrivateKey(),
		gjy.PublicKey(),
		gjy.BlockchainAddress(), //发送者
		zbj.BlockchainAddress(), //接收者
		8)

	//区块链 打包交易  blockchain.AddTransaction做了哪些改进？
	isAdded := blockchain.AddTransaction(
		gjy.BlockchainAddress(),
		zbj.BlockchainAddress(),
		8, // 为什么不能用t.value读取交易的金额？
		gjy.PublicKey(),
		t.GenerateSignature())

	color.HiGreen("这笔交易验证通过吗? %v\n", isAdded)

	// 矿工->孙悟空 (180)
	t2 := wallet.Transfer(
		gjy.PrivateKey(),
		gjy.PublicKey(),
		gjy.BlockchainAddress(),
		swk.BlockchainAddress(),
		180)

	//区块链 打包交易
	isAdded = blockchain.AddTransaction(
		gjy.BlockchainAddress(),
		swk.BlockchainAddress(),
		180,
		gjy.PublicKey(),
		t2.GenerateSignature())

	fmt.Println("这笔交易验证通过吗? ", isAdded)

	// 孙悟空->猪八戒 (80)
	t3 := wallet.NewTransaction(
		swk.PrivateKey(),
		swk.PublicKey(),
		swk.BlockchainAddress(),
		zbj.BlockchainAddress(),
		80)

	//区块链 打包交易
	isAdded = blockchain.AddTransaction(
		swk.BlockchainAddress(),
		zbj.BlockchainAddress(),
		80,
		swk.PublicKey(),
		t3.GenerateSignature())

	fmt.Println("这笔交易验证通过吗? ", isAdded)

	blockchain.Mining()
	blockchain.Print()

	//
	block2, err := blockchain.GetBlockByNumber(2)
	if err != nil {
		log.Fatal(err)
	}
	hash := block2.Hash()

	_, err = blockchain.GetBlockByHash([]byte(hash[:]))
	if err != nil {
		log.Fatal(err)
	}

	blockchain.GetBlockByHash([]byte(hash[:]))

	fmt.Printf("新建钱包成功 %d\n", wallet.NewWallet())
	fmt.Printf("孙悟空[%s] %d\n", swk.BlockchainAddress(), blockchain.CalculateTotalAmount(swk.BlockchainAddress()))
	fmt.Printf("猪八戒[%s] %d\n", zbj.BlockchainAddress(), blockchain.CalculateTotalAmount(zbj.BlockchainAddress()))
	fmt.Printf("矿工[%s]   %d\n", gjy.BlockchainAddress(), blockchain.CalculateTotalAmount(gjy.BlockchainAddress()))

	fmt.Printf("矿工的余额为 %d\n", blockchain.GetBalance(gjy.BlockchainAddress()))
}
